(********************************************************************)
(*	file: 		ADSPCall.p											*)
(*	version:	.5alpha												*)
(* 																	*)
(*	Attempt to establish a line with another entity whose entity	*)
(*  name is passed as a parameter.	Creates the connection data		*)
(* 	block and makes the call asynchronously.						*)
(*																	*)
(*  ADSP does not allow more than one connection at a time between	*)
(*	any two ends.  Therefore, ADSPCall must first check to see 		*)
(* 	whether the two ends are already connected.  If they are, just	*)
(* 	return with no error...											*)
(*																	*)
(* In:	params[1] ::= Entity Name of the NBP entity to call			*)
(*		params[2] ::= Message to send listening data to				*)
(*		params[3] ::= number of retries (optional)					*)
(*		params[4] ::= number of 10-tick intervals between retries	*)
(*		params[5] ::= Input buffer size (optional)					*)
(*		params[6] ::= Output buffer size (optional)					*)
(*																	*)
(* If the entity is already connected, just return with noErr (the	*)
(* call was completed before it was initiated).						*)
(* 																	*)
(* Defaults:	Input Buffer 	= 578								*)
(*				Output Buffer	= 578								*)
(*				Retry count		= 0									*)
(*				Retry interval	= 0									*)
(* Out:	the Result ::= error message, empty if none.				*)
(*																	*)
(* ----------------------------------------------------------------	*)
(* By:		Donald Koscheka											*)
(* Date:	4-Feb-88												*)
(* 			©	Copyright 1988, Apple Computer, Inc.				*)
(*			All Rights Reserved										*)
(*																	*)
(* ----------------------------------------------------------------	*)
(*						Modification History						*)
(* ----------------------------------------------------------------	*)
(*  Date	| By	|	 				Description					*)
(* ----------------------------------------------------------------	*)
(*  4-Feb-88| DK	| file created									*)
(* 12-Feb-88| DK	| user settable buffer sizes & retrans info.	*)
(* 17-Mar-88| DK	| ALPHA RELEASE									*)
(* ----------------------------------------------------------------	*)
(********************************************************************)


(********************************************************************
							Build Sequence

pascal -o "{hpo}"ADSPCall.p.o "{adsp}"ADSPCall.p
link -m ENTRYPOINT  -rt XCMD=1302 -sn Main=ADSPCall¶
	"{hpo}"ADSPCall.p.o¶
	"{libraries}"Interface.o ¶
	"{plibraries}"paslib.o¶
	-o "{hp}"HyperADSPTest
		 
********************************************************************)


{$R-}
{$S ADSPCall}
UNIT Koscheka;

(*******************************************************************)
INTERFACE 
(*******************************************************************)


Uses MemTypes, QuickDraw, OSIntf, ToolIntf, PackIntf, HyperXCmd, AppleTalk, ADSP, adspxcmd;


Procedure EntryPoint( paramPtr : XCmdPtr );


(*******************************************************************)
IMPLEMENTATION
(*******************************************************************)


PROCEDURE ADSPCall( paramPtr: XCmdPtr ); FORWARD;

Procedure EntryPoint( paramPtr : XCmdPtr );
	Begin
		ADSPCall( paramPtr );
	End;
	
	
Procedure ADSPCall( paramPtr : XCmdPtr );
VAR
	adsp		: ADSPPtr;
	error, terr	: OSErr;
	inBufSiz	: Integer;
	outBufSiz	: Integer;
	retry		: Integer;
	interval	: Integer;
	eAddr		: AddrBlock;	
	temp		: Str255;
	cn			: CBPtr;
	nbp 		: NBPPtr;
	found		: BOOLEAN;
	
{$I XCmdGlue.inc }
{$I XCMDADSP.inc }	

(*****************************  ADSPCall	*******************************)
BEGIN
	error 		:= noErr;
	retry 		:= 0;
	interval 	:= 0;
	inBufSiz	:= ATPBSIZE;
	outBufSiz	:= ATPBSIZE;
	found		:= TRUE;	{*** true if this connection already established ***}
	
	IF paramPtr^.paramCount <> 0 THEN 		{*** wouldn't send if no entity given		***}
		IF paramPtr^.params[1]^ <> NIL THEN	{*** need a pointer to a name 				***}
		BEGIN
			adsp := ADSPPtr(RetrieveHandle( GLOBALDSPDATA ));
			IF adsp <> NIL THEN
			BEGIN
				adsp^.checkPoint := RECEIVING;
				{**** Before we go too far, let's look at some of the settings			***}
				IF paramPtr^.params[3] <> NIL THEN	{*** set the retransmit count		***}
					BEGIN
						ZeroToPas( paramPtr^.params[3]^, temp );
						retry := Integer( StrToNum( temp ));
					END;
			
				IF paramPtr^.params[4] <> NIL THEN	{*** Set the retransmit interval	***}
					BEGIN
						ZeroToPas( paramPtr^.params[4]^, temp );
						interval := Integer( StrToNum( temp ));
					END;
			
				IF paramPtr^.params[5] <> NIL THEN	{*** Set the input buffer size		***}
					BEGIN
						ZeroToPas( paramPtr^.params[5]^, temp );
						inBufSiz := Integer( StrToNum( temp ));
					END;
			
				IF paramPtr^.params[6] <> NIL THEN	{*** Set the output buffer size		***}
					BEGIN
						ZeroToPas( paramPtr^.params[6]^, temp );
						outBufSiz := Integer( StrToNum( temp ));
					END;
			
				error := noErr;
				
				{*** (1) Get the entity's address 								***}
				HLock( Handle(paramPtr^.params[1]) );
				eAddr 	:= NBPGetAddress( paramPtr^.params[1]^ );
				HUnlock( Handle( paramPtr^.params[1] ) );

				{*** Walk through the connection list to see if the connection	***}
				{*** already exists.									 		***}
				
				IF LongInt(eAddr) <> 0 THEN { only call if we have a remote end ***}
				BEGIN
					cn := adsp^.ends;
					found := FALSE;
					
					WHILE (NOT found) DO
						IF cn = NIL THEN
							found := TRUE
						ELSE
							IF LongInt( eAddr ) = LongInt( cn^.adr ) THEN
								found := TRUE
							ELSE
								cn := cn^.next;
					
					{*** If the connection already exists, cn will not be NIL 	***}
					{*** so we won't have to reconnect the two ends, just fall	***}
					{*** out, otherwise, try to make the connection.			***}
					
					IF cn = NIL  THEN {*** establish connection ***}
						BEGIN
							cn := DSPCreate(eAddr,inBufSiz,outBufSiz,retry,interval, paramPtr^.params[2] );
							IF cn <> NIL THEN
								BEGIN
									cn^.remName := NBPGetName( eAddr );
									IF cn^.remName = NIL THEN	{*** try to discover the name 	***}
										BEGIN
											nbp := NBPPtr(RetrieveHandle(GLOBALNBPDATA));
											IF nbp <> NIL THEN 
												BEGIN
													SendCardMessage('DoALookUp');
													cn^.remName := NBPGetName( eAddr );
												END;
										END;
				
									WITH cn^.dspPB DO	{*** Now "dial for dollars"	***}
										BEGIN
											ioCRefNum 		:= adsp^.dspRefNum;
											ccbRefNum		:= cn^.ccbRef;
											csCode			:= dspOpen;
											ocMode			:= ocRequest;
											ioCompletion	:= NIL;
											remoteCID		:= 0;	{*** don't know this yet	***}
											localCID		:= 0;	{*** adsp allocates the id	***}
											remoteAddress	:= eAddr;	
											filterAddress.aNet	:= 0;
											filterAddress.aNode	:= 0;
											filterAddress.aSocket:= 0;
											SendSeq			:= 0;
											RecvSeq			:= 0;
											SendWindow		:= 0;
											attnSendSeq		:= 0;
											attnRecvSeq		:= 0;
											ocInterval		:= INTERVAL;
											ocMaximum		:= RETRY;
											error 			:= PBControl( @cn^.dspPB, ASYNC );
										END;
								END;
						END;
				END; {(LongInt(eAddr) <> 0) }
				adsp^.checkPoint := CLOSE_OK;
			END;
		END;
	paramPtr^.returnValue := ErrorReturn( error );
END;

end.
